package top.codecrab.eblog.common.aspect;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import top.codecrab.eblog.common.annotation.AccessLimit;
import top.codecrab.eblog.common.response.R;
import top.codecrab.eblog.config.Constants;
import top.codecrab.eblog.utils.CommonUtils;

import javax.servlet.http.HttpServletRequest;

/**
 * @author 王刚
 * @since 2022年08月04日 9:13
 */
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class ViewCountAspect {

    private final HttpServletRequest request;

    private final StringRedisTemplate stringRedisTemplate;

    @AfterReturning(value = "@annotation(accessLimit)", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result, AccessLimit accessLimit) {
        if (!(joinPoint.getSignature() instanceof MethodSignature)) {
            return;
        }

        if (!(result instanceof R)) {
            return;
        }

        R r = (R) result;
        if (r.getStatus() != 0) {
            return;
        }

        String ip = CommonUtils.getRemoteHost(request);
        String servletPath = request.getServletPath();
        String key = Constants.GLOBAL_REDIS_PREFIX + "visitCount:" + servletPath + ":" + ip;

        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        if (opsForValue.get(key) == null) {
            opsForValue.set(key, "1", accessLimit.duration(), accessLimit.timeUnit());
        }
        opsForValue.increment(key, 1);
    }

}
